package com.yangtzeu.jwc.dao.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;

import com.yangtzeu.jwc.activity.MainActivity;
import com.yangtzeu.jwc.app.MyApplication;
import com.yangtzeu.jwc.business.AppBusiness;
import com.yangtzeu.jwc.businessservice.BusinessHttpCallBack;
import com.yangtzeu.jwc.dao.StudentDao;
import com.yangtzeu.jwc.domain.Course;
import com.yangtzeu.jwc.domain.KbSelection;
import com.yangtzeu.jwc.domain.Sc;
import com.yangtzeu.jwc.domain.Student;
import com.yangtzeu.jwc.domain.XkInfo;
import com.yangtzeu.jwc.utils.ACache;
import com.yangtzeu.jwc.utils.DbUtils;
import com.yangtzeu.jwc.utils.G;
import com.yangtzeu.jwc.utils.UrlParamsUtils;
import com.zjsx.lib.utils.L;
import com.zjsx.lib.utils.StrUtil;

/**
 * 有关用户的操作,需要登录
 * 
 * @author ZhangDI
 */
public class StudentDaoImpl extends BasicDaoImpl implements StudentDao {
    private static StudentDao studentDaoImpl = new StudentDaoImpl();

    private StudentDaoImpl() {
	super();
    }

    public static StudentDao getInstance() {
	return studentDaoImpl;
    }

    public void login(final String username, final String password, final String type, final BusinessHttpCallBack callBack) {
	setValidation(G.LOGIN_PATH, new BusinessHttpCallBack() {

	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		if (callBack != null)
		    callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		// 获取验证成功
		// 设置验证以及参数
		clearParams();
		addValidationParams();
		addCustomParams(G.USER_NUMBER, username);
		addCustomParams(G.USER_PASSWORD, password);
		addCustomParams(G.SELKIND, type);
		addCustomParams(G.BTLOGIN, "");
		login(callBack);
	    }
	});

    }

    public void login(final BusinessHttpCallBack callBack) {
	doHttpRequest(G.LOGIN_PATH, paramsMap, new BusinessHttpCallBack() {
	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		if (callBack != null)
		    callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		if (callBack != null)
		    callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    Document doc = (Document) obj;
		    Student student = new Student();
		    String userInfo = doc.select("#" + G.LOGIN_USERINFO).text();
		    String[] userinfos = userInfo.split(" ");
		    // 如果得到数据分解成三部分说明登陆成功,封装成学生对象返回
		    if (userinfos.length == 3) {
			student.setSno(userinfos[0]);
			student.setSname(userinfos[1]);
			student.setSclass(userinfos[2]);
			student.setSpassword(paramsMap.get(G.USER_PASSWORD));
			MainActivity.student = student;
			new AppBusiness(MyApplication.getInstance()).login();
			loginBrodcast();
			getStudentInfo(null);
			if (callBack != null)
			    callBack.onSuccess(responseBody, "登录成功", false, student);
		    } else {
			if (callBack != null)
			    callBack.onFailure(responseBody, "用户名或密码错误！", false);
		    }
		} catch (Exception e) {
		    if (callBack != null)
			callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }
	}

	);
    }

    private void loginBrodcast(){
	Intent itt = new Intent();
	itt.setAction(G.BROADCAST_LOGIN);
	MyApplication.getInstance().sendBroadcast(itt);
    }
    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.StudentDao#queryBxkJd(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String,
     * com.zhangdi.domain.Student)
     */
    @Override
    public void queryBxkJd(final BusinessHttpCallBack callBack) {
	clearParams();
	addValidationParams();
	addCustomParams(G.EVENTTARGET, "");
	addCustomParams(G.EVENTARGUMENT, "");
	addCustomParams(G.SELYEAR, "" + Calendar.getInstance().get(Calendar.YEAR));
	addCustomParams(G.SELTERM, "1");
	addCustomParams(G.BXKJD, "");
	doHttpRequest(G.INQUERY_SCORE_PATH, paramsMap, new BusinessHttpCallBack() {
	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    Document doc = (Document) obj;
		    Elements jd = doc.select("#" + G.JD);
		    String bxkjd = null;
		    if (jd != null)
			bxkjd = jd.text();
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, bxkjd);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }

	});
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.StudentDao#queryXwkJd(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String,
     * com.zhangdi.domain.Student)
     */
    @Override
    public void queryXwkJd(final BusinessHttpCallBack callBack) {

	// 得到验证后继续发送查询成绩的参数和验证
	clearParams();
	addValidationParams();
	addCustomParams(G.EVENTTARGET, "");
	addCustomParams(G.EVENTARGUMENT, "");
	addCustomParams(G.SELYEAR, "" + Calendar.getInstance().get(Calendar.YEAR));
	addCustomParams(G.SELTERM, "1");
	addCustomParams(G.XWKJD, "");
	doHttpRequest(G.INQUERY_SCORE_PATH, paramsMap, new BusinessHttpCallBack() {

	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    Document doc = (Document) obj;
		    Elements jd = doc.select("#" + G.JD);
		    String xwkJd = null;
		    if (jd != null)
			xwkJd = jd.text();
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, xwkJd);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }

	});
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.StudentDao#queryScore(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String,
     * com.zhangdi.domain.Student)
     */
    @Override
    public void queryScore(final boolean fromCache, final BusinessHttpCallBack callBack) {
	String url = G.INQUERY_SCORE_PATH;
	setValidation(url, new BusinessHttpCallBack() {

	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    clearParams();
		    addValidationParams();
		    addCustomParams(G.EVENTTARGET, G.QUERYALLSCORE);
		    addCustomParams(G.EVENTARGUMENT, "");
		    addCustomParams(G.SELYEAR, Calendar.getInstance().get(Calendar.YEAR) + "");
		    addCustomParams(G.SELTERM, "1");
		    queryScore2(fromCache, callBack);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }

	});
    }

    // 解析网页中的成绩
    public List<Sc> queryScoreFromDoc(Document doc) {
	List<Sc> scores = new ArrayList<Sc>();
	// 得到显示分数的表格
	Elements table = doc.select("#" + G.SCORE_TABLE);
	// 得到每一行数据
	Elements trs = table.select("tr");
	Sc sc;
	// 循环取出成绩数据,并存放到List中
	for (int i = 1; i < trs.size(); i++) {
	    String[] tdvalues = trs.get(i).text().split(" ");
	    if (tdvalues.length == 6) {
		sc = new Sc(MainActivity.student.getSno(), tdvalues[0], tdvalues[2], tdvalues[3], tdvalues[4], tdvalues[5], tdvalues[1]);
		scores.add(sc);
	    }
	}
	return scores;
    }

    public void queryScore2(final boolean fromCache, final BusinessHttpCallBack callBack) {
	String url = G.INQUERY_SCORE_PATH;
	final String cacheName = url + paramsMap.toString();
	String docStr = aCache.getAsString(cacheName);

	if (docStr != null && fromCache) {
	    List<Sc> scores = queryScoreFromDoc(Jsoup.parse(docStr));
	    callBack.onSuccess(null, null, false, scores);
	}
	doHttpRequest(url, paramsMap, new BusinessHttpCallBack() {

	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    List<Sc> scores = queryScoreFromDoc((Document) obj);
		    aCache.put(cacheName, obj.toString(), ACache.TIME_MONTH);
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, scores);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }
	});
    }

    // 通过web页面获得学生信息
    public void getStudentInfoFromDoc(Document doc) throws Exception {
	try {
	    // 学生性别
	    String ssex = doc.select(G.USER_SEX_ID).text();
	    // 学生身份证号
	    String sjid = doc.select(G.USER_SJID_ID).val();
	    // 学生头像地址
	    String sphoto = G.JWC_HOME + doc.select(G.USER_PHOTO_ID).attr("src");

	    MainActivity.student.setSsex(ssex);
	    MainActivity.student.setSjid(sjid);
	    MainActivity.student.setSphoto(sphoto);
	    MainActivity.student.type = "info";
	    loginBrodcast();
	    
	} catch (Exception e) {
	    throw e;
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.zhangdi.dao.impl.StudentDao#getStudentInfo(com.zhangdi.domain.Student
     * )
     */
    @Override
    public void getStudentInfo(final BusinessHttpCallBack callBack) {
	String url = G.USER_INFO_PATH_CET;
	final String cacheName = url;
	String docStr = aCache.getAsString(cacheName);
	if (docStr != null) {
	    try {
		getStudentInfoFromDoc(Jsoup.parse(docStr));
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	}
	doHttpRequest(G.USER_INFO_PATH_CET, new BusinessHttpCallBack() {

	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		if(callBack!=null)
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		if(callBack!=null)
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    getStudentInfoFromDoc((Document) obj);
		    if(callBack!=null)
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, obj);
		    aCache.put(cacheName, obj.toString(), ACache.TIME_MONTH);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }

	});
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.StudentDao#saveStudent(android.content.Context,
     * java.lang.String, java.lang.String)
     */
    @Override
    public void saveStudent(Context context, String name, String password) {

	DbUtils db = null;
	try {
	    db = new DbUtils(context);
	    db.getWritableDatabase().execSQL("insert into student(name,password) values(?,?)", new String[] { name, password });
	    db.close();
	} catch (Exception e) {
	    e.printStackTrace();
	} finally {
	    if (db != null)
		db.close();
	}
    }

    @Override
    public void modifySavedStudent(Context context, String name, String password) {

	DbUtils db = null;
	try {
	    db = new DbUtils(context);
	    db.getWritableDatabase().execSQL("update student set password = ? where name = ?", new String[] { password, name });
	    db.close();
	} catch (Exception e) {
	    e.printStackTrace();
	} finally {
	    if (db != null)
		db.close();
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.zhangdi.dao.impl.StudentDao#getSavedStudent(android.content.Context)
     */
    @Override
    public Student getSavedStudent(Context context) {
	DbUtils db = null;
	Student student = null;
	try {
	    db = new DbUtils(context);
	    Cursor cursor = db.getWritableDatabase().rawQuery("select name,password from student", new String[] {});
	    if (cursor.moveToFirst()) {
		String name = cursor.getString(cursor.getColumnIndex("name"));
		String password = cursor.getString(cursor.getColumnIndex("password"));
		student = new Student();
		student.setSno(name);
		student.setSpassword(password);
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	} finally {
	    db.close();
	}
	return student;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.zhangdi.dao.impl.StudentDao#clearStudent(android.content.Context)
     */
    @Override
    public void clearStudent(Context context) {
	DbUtils db = null;
	try {
	    db = new DbUtils(context);
	    db.getWritableDatabase().execSQL("delete from student");
	} catch (Exception e) {
	    e.printStackTrace();
	} finally {
	    if (db != null)
		db.close();
	}
    }

    /**
     * 查看选课信息
     */
    @Override
    public void getXkInfo(final BusinessHttpCallBack callBack) {
	doHttpRequest(G.XKINFO, new BusinessHttpCallBack() {

	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    Document doc = (Document) obj;
		    XkInfo info = new XkInfo();
		    String lbGxMax = "lbGxMax";
		    info.setLbGxMax(doc.select("#" + lbGxMax).text());
		    String lbZyMax = "lbZyMax";
		    info.setLbZyMax(doc.select("#" + lbZyMax).text());
		    String lbGxxf = "lbGxxf";
		    info.setLbGxxf(doc.select("#" + lbGxxf).text());
		    String lbGxbjgxf = "lbGxbjgxf";
		    info.setLbGxbjgxf(doc.select("#" + lbGxbjgxf).text());
		    String lbGx = "lbGx";
		    info.setLbGx(doc.select("#" + lbGx).text());
		    String lbGxCount = "lbGxCount";
		    info.setLbGxCount(doc.select("#" + lbGxCount).text());
		    String lbGxMaxCount = "lbGxMaxCount";
		    info.setLbGxMaxCount(doc.select("#" + lbGxMaxCount).text());
		    String lbZyxf = "lbZyxf";
		    info.setLbZyxf(doc.select("#" + lbZyxf).text());
		    String lbZybjgxf = "lbZybjgxf";
		    info.setLbZybjgxf(doc.select("#" + lbZybjgxf).text());
		    String lbZy = "lbZy";
		    info.setLbZy(doc.select("#" + lbZy).text());

		    // 年份信息和选课的年份以及学期
		    Elements year_opts = doc.select("#" + G.SELYEAR).select("option");
		    Element year_opt = null;
		    String[] years = new String[year_opts.size()];
		    for (int i = 0; i < year_opts.size(); i++) {
			year_opt = year_opts.get(i);
			if ("selected".equals(year_opt.attributes().get("selected"))) {
			    info.setSelectedYear(year_opt.text());
			}
			years[i] = year_opt.text();
		    }
		    info.setYears(years);
		    year_opt = null;
		    year_opts = null;

		    // 校区
		    Elements xiaoqo_opts = doc.select("#selXiaoqu").select("option");
		    Element xiaoqo_opt = null;
		    String[] xiaoqus = new String[xiaoqo_opts.size()];
		    for (int i = 0; i < xiaoqo_opts.size(); i++) {
			xiaoqo_opt = xiaoqo_opts.get(i);
			if ("selected".equals(xiaoqo_opt.attributes().get("selected"))) {
			    info.setSelectedXiaoqu(xiaoqo_opt.text());
			}
			xiaoqus[i] = xiaoqo_opt.text();
			;
		    }

		    info.setXiqoqus(xiaoqus);
		    xiaoqo_opts = null;
		    xiaoqo_opt = null;

		    // 选课的学期
		    Elements term_opts = doc.select("#" + G.SELTERM).select("option");
		    Element term_opt = null;
		    String[] terms = new String[term_opts.size()];
		    for (int i = 0; i < term_opts.size(); i++) {
			term_opt = term_opts.get(i);
			if ("selected".equals(term_opt.attributes().get("selected"))) {
			    info.setSelectedTerms(term_opt.val());
			}
			terms[i] = term_opt.val();
		    }
		    info.setTerms(terms);
		    term_opt = null;
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, info);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }
	});
    }

    /**
     * 获取已选课程
     */
    @Override
    public void getXkInfo(String selYear, String selTerm, String selXiaoqu, final BusinessHttpCallBack callBack) {
	clearParams();
	addValidationParams();
	addCustomParams(G.EVENTTARGET, "btQuery");
	addCustomParams(G.EVENTARGUMENT, "");
	addCustomParams(G.VIEWSTATE, viewstate);
	addCustomParams(G.EVENTVALIDATION, eventvalidation);
	addCustomParams(G.SELYEAR, selYear);
	addCustomParams(G.SELTERM, selTerm);
	addCustomParams("selXiaoqu", selXiaoqu);

	doHttpRequest(G.XKINFO, paramsMap, new BusinessHttpCallBack() {
	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    Document doc = (Document) obj;
		    // L.d(doc.toString());
		    Elements tables = doc.select("table");
		    Element table = tables.get(tables.size() - 1);
		    // L.d(table.text());
		    Elements trs = table.select("tr");
		    // L.d(trs.size());
		    Element tr = null;
		    Elements tds = null;
		    Element td = null;
		    List<Course> courses = new LinkedList<Course>();
		    Course course = null;
		    for (int i = 1; i < trs.size() - 1; i++) {
			course = new Course();
			tr = trs.get(i);
			tds = tr.select("td");
			// 地零个得到是否可选
			String input = tds.get(0).select("input").toString();
			boolean noDelete = (input == null || "".equalsIgnoreCase(input.trim()));
			if (noDelete || "disabled".equalsIgnoreCase(tds.get(0).select("input").attr("disabled"))) {
			    course.setCanSelect(false);
			} else {
			    course.setCanSelect(true);
			}
			// 第一个列含有链接
			td = tds.get(1);
			Elements es = td.select("a");
			// L.d(es.size());
			Element e = es.get(0);
			e.attributes().get("href");
			// 获取课程的链接信息
			String courseUrl = td.select("a").get(0).attributes().get("href");
			// 从链接中解析出链接中包含的课程编号
			String courseId = UrlParamsUtils.getParams(courseUrl).get("no");
			course.setId(courseId);
			// L.d(courseId);

			// 将每门选修课的信息迭代到一个数组中
			String[] courseInfo = new String[tds.size() - 1];
			for (int j = 1; j < tds.size(); j++) {
			    courseInfo[j - 1] = tds.get(j).text();
			}
			// L.d(tds.size() + "--------");
			// 从数组中取出课程信息,并放到课程对象中.
			course.setCname(courseInfo[0]);
			course.setCredit(courseInfo[1]);
			course.setTime(courseInfo[2]);
			// course.setMaxCount(courseInfo[3]);
			// course.setCount(courseInfo[4]);
			course.setTeacher(courseInfo[3]);
			course.setClass1(courseInfo[4]);
			course.setType(courseInfo[5]);

			courses.add(course);
		    }
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, courses);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }
	});
    }

    @Override
    public void getGxk(final String xiaoqu, final BusinessHttpCallBack callBack) {
	// 首先更新一下验证码
	getXkInfo(new BusinessHttpCallBack() {

	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		getGxkList((XkInfo) obj, xiaoqu, callBack);
	    }

	});
    }

    public void getGxkList(final XkInfo info, final String Xiaoqu, final BusinessHttpCallBack callBack) {
	clearParams();
	addValidationParams();
	addCustomParams(G.EVENTTARGET, "btAddgx");
	addCustomParams(G.EVENTARGUMENT, "");
	addCustomParams(G.VIEWSTATE, viewstate);
	addCustomParams(G.EVENTVALIDATION, eventvalidation);
	addCustomParams(G.SELYEAR, "2014");
	addCustomParams(G.SELTERM, "2");
	addCustomParams("selXiaoqu", Xiaoqu);
	doHttpRequest(G.XKINFO, paramsMap, new BusinessHttpCallBack() {
	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    Document doc = (Document) obj;
		    // L.d(doc.toString());
		    Elements tables = doc.select("table");
		    Element table = tables.get(tables.size() - 1);
		    // L.d(table.text());
		    Elements trs = table.select("tr");
		    // L.d(trs.size());
		    Element tr = null;
		    Elements tds = null;
		    Element td = null;
		    List<Course> courses = new ArrayList<Course>();
		    Map GxkInfo = new HashMap();
		    Course course = null;
		    for (int i = 1; i < trs.size() - 1; i++) {
			course = new Course();
			tr = trs.get(i);
			tds = tr.select("td");
			// 地零个得到是否可选
			if ("disabled".equalsIgnoreCase(tds.get(0).select("input").attr("disabled"))) {
			    course.setCanSelect(false);
			} else {
			    course.setCanSelect(true);
			}
			// 第一个列含有链接
			td = tds.get(1);
			Elements es = td.select("a");
			// L.d(es.size());
			Element e = es.get(0);
			e.attributes().get("href");
			// 获取课程的链接信息
			String courseUrl = td.select("a").get(0).attributes().get("href");
			// 从链接中解析出链接中包含的课程编号
			String courseId = UrlParamsUtils.getParams(courseUrl).get("no");
			course.setId(courseId);
			// L.d(courseId);

			// 将每门选修课的信息迭代到一个数组中
			String[] courseInfo = new String[tds.size() - 1];
			for (int j = 1; j < tds.size(); j++) {
			    courseInfo[j - 1] = tds.get(j).text();
			}
			// L.d(tds.size() + "--------");
			// 从数组中取出课程信息,并放到课程对象中.
			course.setCname(courseInfo[0]);
			course.setCredit(courseInfo[1]);
			course.setTime(courseInfo[2]);
			course.setMaxCount(courseInfo[3]);
			course.setCount(courseInfo[4]);
			// course.setTeacher(courseInfo[3]);
			course.setClass1(courseInfo[5]);
			course.setType(courseInfo[6]);
			courses.add(course);
		    }
		    GxkInfo.put("xkInfo", info);
		    GxkInfo.put("gxkList", courses);
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, GxkInfo);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }

	});
    }

    @Override
    public void xxGxk(String courseId, final BusinessHttpCallBack callBack) {
	String add = G.JWC_HOME + "/Xk2.aspx?rwh=" + courseId + "&action=1";
	doHttpRequest(add, new BusinessHttpCallBack() {

	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    Document doc = (Document) obj;
		    String resuleMsg = doc.toString();
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, resuleMsg);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }

	});
    }

    @Override
    public void qxxxGxk(Student student, String courseId, final BusinessHttpCallBack callBack) {
	String delete = G.JWC_HOME + "/Xk2.aspx?rwh=" + courseId + "&action=2";
	doHttpRequest(delete, new BusinessHttpCallBack() {

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		Document doc = (Document) obj;
		String data = doc.toString();
		if (data.contains("删除成功")) {
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, obj);
		} else {
		    callBack.onFailure(responseBody, "删除失败，请尝试在网页上操作！", isNoticeDialog);
		}
	    }

	});
    }

    public void changePassword(final String newPassword, final BusinessHttpCallBack callBack) {
	String path = G.CHANGE_PASSWORD;
	doHttpRequest(path, new BusinessHttpCallBack() {

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		clearParams();
		addValidationParams();
		addCustomParams("OldPwd", MainActivity.student.getSpassword());
		addCustomParams("ps2", newPassword);
		addCustomParams("btOK", "ȷ��");
		changePassword(callBack);
	    }

	});
    }

    public void changePassword(final BusinessHttpCallBack callBack) {
	String path = G.CHANGE_PASSWORD;
	doHttpRequest(path, paramsMap, new BusinessHttpCallBack() {
	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		Document doc = (Document) obj;
		String data = doc.toString();
		if (data.contains("密码修改成功")) {
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, obj);
		} else {
		    callBack.onFailure(responseBody, doc.toString(), isNoticeDialog);
		}
	    }

	});
    }

    public boolean getKbSelectionFromDoc(Document doc, BusinessHttpCallBack callBack) {
	KbSelection kbSelection = new KbSelection();
	// 选课的学期
	Map<String, String> terms = new LinkedHashMap<String, String>();
	Elements term_opts = doc.select("#" + G.SELTERM).select("option");
	Element term_opt = null;
	for (int i = 0; i < term_opts.size(); i++) {
	    term_opt = term_opts.get(i);
	    terms.put(term_opt.text(), term_opt.val());
	    if ("selected".equals(term_opt.attributes().get("selected"))) {
		kbSelection.setSelectedTerm(term_opt.text());
	    }
	}
	kbSelection.setTerms(terms);
	term_opt = null;
	term_opts = null;
	// 年份信息和选课的年份以及学期
	Elements year_opts = doc.select("#" + G.SELYEAR).select("option");
	Element year_opt = null;
	Map<String, String> years = new LinkedHashMap<String, String>();
	for (int i = 0; i < year_opts.size(); i++) {
	    year_opt = year_opts.get(i);
	    years.put(year_opt.text(), year_opt.val());
	    if ("selected".equals(year_opt.attributes().get("selected"))) {
		kbSelection.setSelectedYear(year_opt.text());
	    }
	}
	kbSelection.setYears(years);
	year_opt = null;
	year_opts = null;
	// 获取课表类别
	Elements kblb_opts = doc.select("#" + G.SELKBLB).select("option");
	Element kblb_opt = null;
	Map<String, String> kblbs = new LinkedHashMap<String, String>();
	for (int i = 0; i < kblb_opts.size(); i++) {
	    kblb_opt = kblb_opts.get(i);
	    kblbs.put(kblb_opt.text(), kblb_opt.val());
	}
	kbSelection.setKblbs(kblbs);
	kblb_opt = null;
	kblb_opts = null;
	// 获取部门
	Elements dept_opts = doc.select("#" + G.SELDEPART).select("option");
	Element dept_opt = null;
	Map<String, String> depts = new LinkedHashMap<String, String>();
	for (int i = 0; i < dept_opts.size(); i++) {
	    dept_opt = dept_opts.get(i);
	    if(!StrUtil.isEmpty((dept_opt.text()))){
		depts.put(dept_opt.text(), dept_opt.val());
	    }
	}
	kbSelection.setDepts(depts);
	dept_opt = null;
	dept_opts = null;
	return getClassByDoc(doc, kbSelection, callBack);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.JwcDao#getKbSelection()
     */
    @Override
    public void getKbSelection(final BusinessHttpCallBack callBack) {
	doHttpRequest(G.KB_PATH, new BusinessHttpCallBack() {

	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    getKbSelectionFromDoc((Document) obj, callBack);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }
	});

    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.JwcDao#queryClass(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void queryClass(String selYear, String selTerm, String selDepart, String selClass, final BusinessHttpCallBack callBack) {
	clearParams();
	addValidationParams();
	addCustomParams(G.EVENTTARGET, G.SELDEPART);
	addCustomParams(G.EVENTARGUMENT, "");
	addCustomParams(G.LASTFOCUS, "");
	addCustomParams(G.VIEWSTATE, viewstate);
	addCustomParams(G.EVENTVALIDATION, eventvalidation);
	addCustomParams(G.SELYEAR, selYear);
	addCustomParams(G.SELTERM, selTerm);
	addCustomParams(G.SELKBLB, 1 + "");
	addCustomParams(G.SELDEPART, selDepart);
	addCustomParams(G.SELCLASS, selClass);
	String url = G.KB_PATH;
	final String cacheName = url + paramsMap.toString();
	String docStr = aCache.getAsString(cacheName);

	if (docStr != null) {
	    boolean isParseOk = getClassByDoc(Jsoup.parse(docStr), null, callBack);
	    if (isParseOk) {
		return;
	    }
	}
	doHttpRequest(G.KB_PATH, paramsMap, new BusinessHttpCallBack() {
	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		Document doc = (Document) obj;
		aCache.put(cacheName, doc.toString(), ACache.TIME_MONTH);
		getClassByDoc(doc, null, callBack);
	    }
	});
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.JwcDao#getClassByDoc(org.jsoup.nodes.Document)
     */
    @Override
    public boolean getClassByDoc(Document doc, KbSelection kbSelection, BusinessHttpCallBack callBack) {
	try {
	    Elements class_opts = doc.select("#" + G.SELCLASS).select("option");
	    Element class_opt = null;
	    Map<String, String> classes = new LinkedHashMap<String, String>();
	    for (int i = 0; i < class_opts.size(); i++) {
		class_opt = class_opts.get(i);
		classes.put(class_opt.text(), class_opt.val());
	    }
	    class_opt = null;
	    class_opts = null;
	    if (kbSelection != null) {
		kbSelection.setClasses(classes);
		callBack.onSuccess(null, null, false, kbSelection);
	    } else {
		callBack.onSuccess(null, null, false, classes);
	    }
	    return true;
	} catch (Exception e) {
	    callBack.onFailure(null, "教务处服务器异常！", false);
	    return false;
	}
    }

    public String[][] queryKbFromDoc(Document doc) {
	String[][] kebiao = null;
	Elements trs = doc.select("#" + G.DGKB).select("tr");
	Element tr = null;
	Elements tds = null;
	Element td = null;
	kebiao = new String[trs.size() - 1][7];
	// 得到表格,拆分后放到数组返回.
	for (int i = 1; i < trs.size(); i++) {
	    tr = trs.get(i);
	    tds = tr.select("td");
	    for (int j = 1; j < tds.size(); j++) {
		td = tds.get(j);
		kebiao[i - 1][j - 1] = td.text();
	    }
	}
	trs = null;
	tr = null;
	tds = null;
	td = null;
	L.d("课表" + kebiao[0][0] + kebiao[0][1]);
	return kebiao;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.zhangdi.dao.impl.JwcDao#queryKb(java.lang.String,
     * java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void queryKb(String selYear, String selTerm, String selDepart, String selClass, final BusinessHttpCallBack callBack) {
	clearParams();
	addValidationParams();
	addCustomParams(G.EVENTTARGET, G.BTQUERY);
	addCustomParams(G.EVENTARGUMENT, "");
	addCustomParams(G.LASTFOCUS, "");
	addCustomParams(G.VIEWSTATE, viewstate);
	addCustomParams(G.EVENTVALIDATION, eventvalidation);
	addCustomParams(G.SELYEAR, selYear);
	addCustomParams(G.SELTERM, selTerm);
	addCustomParams(G.SELKBLB, 1 + "");
	addCustomParams(G.SELDEPART, selDepart);
	addCustomParams(G.SELCLASS, selClass);
	String url = G.KB_PATH;
	final String cacheName = url + paramsMap.toString();
	String docStr = aCache.getAsString(cacheName);
	if (docStr != null) {
	    String[][] kebiao = queryKbFromDoc(Jsoup.parse(docStr));
	    callBack.onSuccess(null, null, false, kebiao);
	    if (kebiao != null && kebiao.length != 0)
		return;
	}
	doHttpRequest(url, paramsMap, new BusinessHttpCallBack() {
	    @Override
	    public void onProgress(int bytesWritten, int totalSize) {
		callBack.onProgress(bytesWritten, totalSize);
	    }

	    @Override
	    public void onFailure(byte[] responseBody, String failuremsg, boolean isNoticeDialog) {
		callBack.onFailure(responseBody, failuremsg, isNoticeDialog);
	    }

	    @Override
	    public void onSuccess(byte[] responseBody, String successMsg, boolean isNoticeDialog, Object obj) {
		try {
		    Document doc = (Document) obj;
		    String[][] kebiao = queryKbFromDoc(doc);
		    aCache.put(cacheName, doc.toString(), ACache.TIME_MONTH);
		    callBack.onSuccess(responseBody, successMsg, isNoticeDialog, kebiao);
		} catch (Exception e) {
		    callBack.onFailure(responseBody, "教务处服务器异常！", false);
		}
	    }

	});
    }
}
